package com.ecoolex.ying.space.core.manager;

import com.alibaba.fastjson.JSON;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.ying.space.core.dao.GoodsAttachmentDAO;
import com.ecoolex.ying.space.entity.Goods;
import com.ecoolex.ying.space.entity.GoodsAttachment;
import com.ecoolex.ying.space.entity.GoodsAttachment.Column;
import com.ecoolex.ying.space.entity.GoodsAttachmentExample;
import com.ecoolex.ying.space.entity.GoodsWithBLOBs;
import com.ecoolex.ying.space.enums.GoodsAttachmentType;
import com.ecoolex.ying.space.pojo.EditGoodsAttachmentDTO;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class GoodsAttachmentManager {
    @Autowired
    private GoodsAttachmentDAO dao;

    public void create(Goods goods, String createUser) {
        List<GoodsAttachment> attachments = Lists.newArrayList();
        for (GoodsAttachmentType attachmentType : GoodsAttachmentType.values()) {
            GoodsAttachment attachment = new GoodsAttachment();
            attachment.setGoodsId(goods.getGoodsId());
            attachment.setType(attachmentType.real());
            attachment.setStorageIds("[]");
            attachment.setNumber(0);
            attachment.setDeleted(GoodsAttachment.NOT_DELETED);
            attachment.setCreateUser(createUser);
            attachment.setCreateTime(Date.from(Instant.now()));
            attachment.setUpdateUser(createUser);
            attachment.setUpdateTime(Date.from(Instant.now()));
            attachments.add(attachment);
        }

        dao.batchInsert(attachments);
    }

    private void verify(EditGoodsAttachmentDTO edit) {
        BizAssert.isTrue(Check.notNull(edit.getType()), ResultCode.VERIFY.build(11), "类型不能为空");
        BizAssert.isTrue(Check.notNull(edit.getStorageIds()), ResultCode.VERIFY.build(12), "存储Ids不能为空");

        for (String storageId : edit.getStorageIds()) {
            BizAssert.isTrue(Check.notNullOrTrimEmpty(storageId), ResultCode.VERIFY.build(13), "存储Id不能为空");
        }
    }

    @Transactional
    public void update(Goods goods, EditGoodsAttachmentDTO[] edits, String updateUser) {
        BizAssert.isTrue(Check.notNullOrEmpty(edits), "附件不能为空");
        BizAssert.isTrue(edits.length == 3, "附件数据必须是三条");

        for (EditGoodsAttachmentDTO edit : edits) {
            verify(edit);

            GoodsAttachment record = new GoodsAttachment();
            record.setStorageIds(JSON.toJSONString(edit.getStorageIds()));
            record.setNumber(edit.getStorageIds().length);
            record.setUpdateUser(updateUser);
            record.setUpdateTime(Date.from(Instant.now()));

            GoodsAttachmentExample example = new GoodsAttachmentExample();
            example.createCriteria()
                    .andGoodsIdEqualTo(goods.getGoodsId())
                    .andTypeEqualTo(edit.getType())
                    .andDeletedEqualTo(GoodsAttachment.NOT_DELETED);

            int row = dao.updateByExampleSelective(record, example, Column.storageIds, Column.number, Column.updateUser, Column.updateTime);
            BizAssert.isTrue(row == 1, ResultCode.BIZ.build(1), "商品附件更新失败");
        }
    }

    public void deleteByGoodsId(Integer goodsId, String updateUser) {
        GoodsAttachment record = new GoodsAttachment();
        record.setDeleted(GoodsAttachment.IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        GoodsAttachmentExample example = new GoodsAttachmentExample();
        example.createCriteria()
                .andGoodsIdEqualTo(goodsId)
                .andDeletedEqualTo(GoodsAttachment.NOT_DELETED);

        dao.updateByExampleSelective(record, example, Column.deleted, Column.updateUser, Column.updateTime);
    }

    public List<GoodsAttachment> queryByGoodsId(Integer goodsId) {
        GoodsAttachmentExample example = new GoodsAttachmentExample();
        example.createCriteria().andGoodsIdEqualTo(goodsId).andDeletedEqualTo(GoodsAttachment.NOT_DELETED);
        return dao.selectByExampleWithBLOBs(example);
    }

    public GoodsAttachment getById(Integer attachmentId) {
        return dao.selectByPrimaryKeyWithLogicalDelete(attachmentId, GoodsAttachment.NOT_DELETED);
    }

    public GoodsAttachment getByGoodsIdAndType(Integer goodsId, Integer type) {
        GoodsAttachmentExample example = new GoodsAttachmentExample();
        example.createCriteria()
                .andGoodsIdEqualTo(goodsId)
                .andTypeEqualTo(type)
                .andDeletedEqualTo(GoodsAttachment.NOT_DELETED);
        return dao.selectOneByExampleWithBLOBs(example);
    }
}